<template>
  <div class="FormGenerator">
    <div class="leftPanel">
      <div class="base">
        <div class="title bold">基础组件</div>
        <div class="list">
          <div class="itemBtn" :style="{ borderColor: colorList[colorIndex] }" @click="addItem('text')">文本框</div>
          <div class="itemBtn" :style="{ borderColor: colorList[colorIndex] }" @click="addItem('textarea')">文本域</div>
          <div class="itemBtn" :style="{ borderColor: colorList[colorIndex] }" @click="addItem('number')">数字框</div>
          <div class="itemBtn" :style="{ borderColor: colorList[colorIndex] }" @click="addItem('password')">密码框</div>
          <div class="itemBtn" :style="{ borderColor: colorList[colorIndex] }" @click="addItem('radio')">单选框组</div>
          <div class="itemBtn" :style="{ borderColor: colorList[colorIndex] }" @click="addItem('checkbox')">多选框组</div>
          <div class="itemBtn" :style="{ borderColor: colorList[colorIndex] }" @click="addItem('datetime')">日期选择</div>
          <div class="itemBtn" :style="{ borderColor: colorList[colorIndex] }" @click="addItem('select')">下拉单选</div>
          <!-- <div class="itemBtn" :style="{ borderColor: colorList[colorIndex] }" @click="addItem('')">下拉多选</div> -->
        </div>
      </div>
    </div>
    <div class="centerPreview">
      <div class="btnRow">
        <a-button @click="formGeneratorOpera('clearAll')">清空</a-button>
        <a-button type="primary" style="margin-left: 20px;" @click="formGeneratorOpera('exportJSON')">导出JSON</a-button>
        <slot name="operaRow"></slot>
      </div>
      <div class="priview scroll">
        <div :class="['templateItem', currentFormItem == index ? 'current' : '']" v-for="(item, index) in templateList"
          :key="index" @click="currentFormItem = index">
          <div class="label">{{ item.label }}</div>
          <div class="inputContent" v-if="item.type == 'input' && item.options.type == 'text'">
            <a-input v-model:value="modelData[item.modelValue]" :placeholder="item.options.placeholder"
              :disabled="item.options.disabled" :defaultValue="item.options.defaultValue" />
          </div>
          <div class="inputContent" v-if="item.type == 'input' && item.options.type == 'number'">
            <a-input-number v-model:value="modelData[item.modelValue]" :disabled="item.options.disabled" :defaultValue="item.options.defaultValue"
              :min="item.options.min == undefined ? 'Infinity' : item.options.min"
              :max="item.options.max == undefined ? 'Infinity' : item.options.max"
              :style="{ width: item.options.width }" />
          </div>
          <div class="inputContent" v-if="item.type == 'input' && item.options.type == 'password'">
            <a-input-password v-model:value="modelData[item.modelValue]" :placeholder="item.options.placeholder"
              :defaultValue="item.options.defaultValue" :disabled="item.options.disabled" />
          </div>
          <div class="inputContent" v-if="item.type === 'textarea'">
            <a-textarea v-model:value="modelData[item.modelValue]" :placeholder="item.options.placeholder"
              :defaultValue="item.options.defaultValue" :disabled="item.options.disabled" />
          </div>
          <div class="inputContent" v-if="item.type === 'select'">
            <a-select v-model:value="modelData[item.modelValue]" style="width: 120px" :disabled="item.options.disabled">
              <a-select-option v-for="(child, index2) in item.options.children" :key="index2" :value="child.value">{{
                  child.name
              }}</a-select-option>
            </a-select>
          </div>
          <div class="inputContent" v-if="item.type === 'checkbox'">
            <a-checkbox-group v-model:value="modelData[item.modelValue]">
              <a-checkbox v-for="(child, index2) in item.options.children" :key="index2" :value="child.value">{{
                  child.name
              }}</a-checkbox>
            </a-checkbox-group>
          </div>
          <div class="inputContent" v-if="item.type === 'radio'">
            <a-radio-group v-model:value="modelData[item.modelValue]">
              <a-radio v-for="(child, index2) in item.options.children" :key="index2" :value="child.value">{{ child.name
              }}</a-radio>
            </a-radio-group>
          </div>
          <div class="inputContent" v-if="item.type === 'datetime'">
            <a-date-picker show-time v-model:value="modelData[item.modelValue]"
              :placeholder="item.options.placeholder" />
          </div>
          <div class="inputContent" v-if="item.type === 'picker'">
            <a-select v-model:value="modelData[item.modelValue]" style="width: 120px" disabled>
              <a-select-option v-for="(child, index2) in item.options.children" :key="index2" :value="child.value">{{
                  child.name
              }}</a-select-option>
            </a-select>
          </div>
          <div class="iconContainer pointer">
            <MIcon name="youhuiquan" :size="'1.5rem'" :color="'#fff'" @click="operaItem('copy', index, item)"></MIcon>
            <MIcon name="delete" :size="'1.5rem'" :color="'#fff'" @click="operaItem('delete', index, item)"></MIcon>
          </div>
        </div>
      </div>
    </div>

    <div class="rightPanel">
      <a-tabs v-model:activeKey="tabKey" style="width: 100%;">
        <a-tab-pane :key="1" tab="组件配置">
          <div class="componentConfig scroll" v-if="templateList && templateList.length > 0 && templateList[currentFormItem]">
            <a-form :model="templateList[currentFormItem]" name="basic" :layout="'vertical'">
              <a-form-item label="ID(字段的唯一key)" name="ID">
                <a-input v-model:value="templateList[currentFormItem].modelValue" :disabled="true" />
              </a-form-item>
              <a-form-item label="标题">
                <a-input v-model:value="templateList[currentFormItem].label" />
              </a-form-item>
              <a-form-item label="默认值">
                <a-input v-model:value="templateList[currentFormItem].options.defaultValue"
                  @change="changeDefaultValue" />
              </a-form-item>
              <a-form-item label="最大值" v-if="templateList[currentFormItem].options.type == 'number'">
                <a-input-number v-model:value="templateList[currentFormItem].options.max" style="width: 100%;" />
              </a-form-item>
              <a-form-item label="最小值" v-if="templateList[currentFormItem].options.type == 'number'">
                <a-input-number v-model:value="templateList[currentFormItem].options.min" style="width: 100%;" />
              </a-form-item>
              <a-checkbox v-model:checked="templateList[currentFormItem].options.disabled">禁用</a-checkbox>
              <a-form-item label="选项"
                v-if="templateList[currentFormItem].type == 'checkbox' || templateList[currentFormItem].type == 'radio' || templateList[currentFormItem].type == 'select'">
                <div class="row" v-for="(item, index) in templateList[currentFormItem].options.children" :key="index">
                  <div class="left">
                    <div class="child">
                      <div class="label">选项名称</div>
                      <a-input v-model:value="item.name" style="width: 70%;" />
                    </div>
                    <div class="child">
                      <div class="label">选项值</div>
                      <a-input v-model:value="item.value" style="width: 70%;" />
                    </div>
                  </div>
                  <div class="right">
                    <MIcon name="delete" :size="'1.5rem'" @click="operaItem('deleteChild', index, item)"></MIcon>
                  </div>
                </div>
                <a-button @click="operaItem('addChild', -1 , null)">添加一项</a-button>
              </a-form-item>
            </a-form>
          </div>
        </a-tab-pane>
      </a-tabs>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { ITemplateJSON } from '../FormParse/FormParse';
import MIcon from '../MIcon.vue';
import { formType, generatorItem, IFormGeneratorExpose } from './FormGenerator';

export interface IFormGeneratorProps {
  template: ITemplateJSON[]
}

const props = withDefaults(defineProps<IFormGeneratorProps>(), {})




let tabKey = ref(1)

let colorList = ['#f10000', '#ff7b00', '#09ff00', '#00ffea', '#8c00ff', '#000000']
let colorIndex = ref(0)
let timer: any
const startChangeColor = () => {
  if (timer) clearInterval(timer)
  timer = setInterval(() => {
    if (colorIndex.value >= colorList.length) {
      colorIndex.value = 0
    } else {
      colorIndex.value++
    }
  }, 1000)
}
startChangeColor()

// 模板列表
let templateList = ref<ITemplateJSON[]>(props.template)
let currentFormItem = ref(0)
// 表单数据
const modelData = ref<any>({})

props.template.forEach(item => {
  if(item.options.defaultValue) {
    console.log(item.modelValue);
    modelData[item.modelValue] = item.options.defaultValue
  }
})

const addItem = (type: formType) => {
  let item = generatorItem(type)
  templateList.value.push(item!)
  currentFormItem.value = templateList.value.length - 1
}

// 表单组件操作
const operaItem = (opera: string, index: number, item: ITemplateJSON | null) => {
  if (opera == 'copy') {
    let item: ITemplateJSON
    if (templateList.value[index].type == 'input') {
      item = generatorItem(templateList.value[index].options.type!)!
    } else {
      item = generatorItem(templateList.value[index].type! as formType)!
    }
    templateList.value.splice(index, 0, item)
  } else if(opera == 'delete'){
    templateList.value.splice(index, 1)
  }else if(opera == 'deleteChild') {
    templateList.value[currentFormItem.value].options.children.splice(index, 1)
  }else if(opera == 'addChild') {
    let lastIndex = Number(templateList.value[currentFormItem.value].options.children.length) - 1
    let lastChild = templateList.value[currentFormItem.value].options.children[lastIndex]
    templateList.value[currentFormItem.value].options.children.push({ name: '选项' + (lastIndex + 2) , value: '选项' + (lastIndex + 2) })
  }
}

const changeDefaultValue = (e: any) => {
  modelData.value[templateList.value[currentFormItem.value].modelValue] = templateList.value[currentFormItem.value].options.defaultValue
}

// 生成器组件操作
const formGeneratorOpera = (opera: string) => {
  if(opera == 'clearAll') {
    templateList.value = []
  }
  if(opera == 'exportJSON') {
    console.log(templateList.value)
  }
}

defineExpose<IFormGeneratorExpose>({ getTemplateJSON: () => templateList.value })


</script>

<style scoped lang='scss'>
.FormGenerator {
  width: 100%;
  height: 100%;
  background-color: #fff;
  box-sizing: border-box;
  display: flex;

  .leftPanel {
    width: 300px;
    min-height: 100%;
    box-sizing: border-box;
    padding: 40px 30px;
    border-right: solid 2px #f0f0f0;

    .list {
      width: 100%;
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
      margin-top: 20px;

      .itemBtn {
        width: 45%;
        display: flex;
        justify-content: center;
        align-items: center;
        background-color: rgba(218, 218, 218, 0.267);
        height: 30px;
        cursor: pointer;
        transition: all 1s ease;
        margin-top: 10px;
        border: dashed 1px #8c00ff;
      }

      .itemBtn:hover {
        transform: scale(1.03);
        box-shadow: 0px 0px 3px #5f5f5f;
      }
    }

  }

  .centerPreview {
    width: calc(100% - 650px);
    height: 100%;
    box-sizing: border-box;
    padding: 20px 20px;
    border-right: solid 2px #f0f0f0;

    .btnRow {
      min-height: 80px;
    }

    .priview {
      width: 100%;
      height: calc(100% - 80px);
      background-color: #f0f0f0;
      box-sizing: border-box;
      padding: 10px;

      .templateItem {
        width: 100%;
        display: flex;
        margin-top: 10px;
        align-items: center;
        background-color: #fff;
        border: dashed 1px #5f5f5f;
        box-sizing: border-box;
        padding: 30px 10px;
        position: relative;

        .iconContainer {
          position: absolute;
          bottom: 0;
          right: 0;
          display: flex;
          background-color: #3892ff;
          box-sizing: border-box;
          padding: 1px 5px;
          border-radius: 10px 0 0 0;
        }

        .label {
          margin-right: 10px;
          width: auto;
        }

        .inputContent {
          flex-grow: 1;
        }
      }

      .current {
        border: solid 2px #3892ff;
      }

    }

  }

  .rightPanel {
    width: 344px;
    min-height: 100%;
    box-sizing: border-box;
    padding: 15px 20px;
    .row {
      width: 100%;
      display: flex;
      margin-bottom: 10px;
      .left {
        width: calc(100% - 60px);
        .child {
          display: flex;
          .label{ width: 30%; }
        }
      }
      .right {
        width: 60px;
      }
    }

    .componentConfig {
      width: 100%;
      height: 860px;
    }
  }
}
</style>